using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using IGGCore;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;

namespace TxtTFSEditor
{
    /// <summary>
    /// The manager of the command line side of the application
    /// Information requests are sent to the main channel via events
    /// 
    /// THREE VIEWS: 
    /// 1- GAMEVIEW - Games are goin' on
    /// 2- MORNINGVIEW - The morning after games
    /// 3- OFFDAY - All other days
    /// </summary>
    public class OldTxtManager
    {
        private static string NEXT_ACTION = "NONE";

        private enum VIEWS { GAMEVIEW, MORNINGVIEW, OFFDAY };
        private VIEWS m_currentView = VIEWS.OFFDAY;

        private BoxesManager m_boxesManager;
        private bool m_updated = false;
        private MainChannel m_mainChannel = null;
        private DateTime m_lastRefresh;
        private DateTime m_currentDate = DateTime.Now;
        private bool m_statsLoaded = false;
        private bool m_needBoxes = true;
        private bool m_closing = false;

        private Thread m_twitterThread;
        private bool m_twitterThreadActive = false;

        /// <summary>
        /// Main constructor
        /// </summary>
        public OldTxtManager()
        {
            m_boxesManager = new BoxesManager();
            m_mainChannel = new MainChannel();
            if (ToolBox.YesterdayScores())
            {
                m_currentDate = DateTime.Now.AddDays(-1);
            }
        }

        private void LoadStandings()
        {
            Thread.Sleep(30 * 1000);
            m_lastRefresh = DateTime.Now;
            m_mainChannel.UpdateStandings();
        }

        public void StartApplication()
        {
            string folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            // start the tray manager if not already started
            if (Process.GetProcessesByName("SysTrayManager").Length < 1)
            {
                Process.Start(Path.Combine(folder, "SysTrayManager.exe"));
            }
            
            try
            {
                // Start Registry Monitor Thread
                Thread threadRegistryMonitor = new Thread(new ThreadStart(MonitorRegistryAction));
                threadRegistryMonitor.Start();

                // Start Standings Thread
                Thread threadStandings = new Thread(new ThreadStart(LoadStandings));
                threadStandings.Start();

                m_updated = ReloadScoreboard(null);
                if (m_mainChannel.ScoreBoard.GamesList.Games.Count > 0)
                {
                    // THERE ARE GAMES!
                    if (ToolBox.YesterdayScores())
                    {
                        m_currentView = VIEWS.MORNINGVIEW;
                    }
                    else
                    {
                        m_currentView = VIEWS.GAMEVIEW;
                    }

                    StartGamesThreads();

                    //m_mainChannel.UpdateBoxscore(m_currentDate);
                    //m_mainChannel.UpdateNews(false);
                    //m_boxesManager.InitializeBoxedGames(m_mainChannel.ScoreBoard);
                    //m_mainChannel.UpdateTweets();
                    //m_mainChannel.UpdateAllBoxscores(m_currentDate, m_mainChannel.ScoreBoard);
                    //ShowGameView();
                }
                else // NO GAMES TO REPORT
                {
                    m_currentView = VIEWS.OFFDAY;
                    m_lastRefresh = DateTime.Now;
                    Thread thread = new Thread(new ThreadStart(StartInfoNewsThreads));
                    thread.Start();
                }
                m_mainChannel.ScoreBoardDated = m_mainChannel.ScoreBoard;
                m_lastRefresh = DateTime.Now;

                // START MAIN LOOP
                // WHEN WE CREATE A NEW PAPER, WE CHECK THE AVAILABILITY OF STANDINGS, STATS
                // IF NOT, TOO BAD. IF YES, THEY ARE INCLUDED

                do
                {
                    #region oldcode

                    //if (Output.IsConsoleKeyAvailable()) // THE USER HAS PRESSED A COMMAND KEY
                    //{
                    //    info = Console.ReadKey(true);
                    //    key = info.Key;
                    //    if (ToolBox.CheckArrowKey(info))
                    //    {
                    //        m_needBoxes = true;
                    //        m_boxesManager.ManageSelectionNavigator(m_mainChannel.ScoreBoard, info.Key);
                    //        Modes.ManageArrowChange();
                    //        m_mainChannel.UpdateBoxscore(m_currentDate);
                    //        ShowGameView();
                    //    }
                    //    else
                    //    {
                    //        if (info.Key != ConsoleKey.W)
                    //        {
                    //            m_twitterThreadActive = false;
                    //        }
                    //        if (info.Key == ConsoleKey.F5)
                    //        {
                    //            //m_updated = ReloadScoreboard(m_mainChannel.ScoreBoard.SelectedGame.Id);
                    //            //m_mainChannel.UpdateBoxscore(m_currentDate);
                    //            m_mainChannel.UpdateTweets();
                    //            m_mainChannel.UpdateAllBoxscores(m_currentDate, m_mainChannel.ScoreBoard);
                    //            m_lastRefresh = DateTime.Now;
                    //        }
                    //        else if (info.Key == ConsoleKey.F2)
                    //        {
                    //            // GO BACK A DAY
                    //            m_currentDate = m_currentDate.AddDays(-1);
                    //            m_updated = ReloadScoreboard(null);
                    //            m_mainChannel.UpdateBoxscore(m_currentDate);
                    //            m_lastRefresh = DateTime.Now;
                    //        }
                    //        else if (info.Key == ConsoleKey.F3)
                    //        {
                    //            // A DAY LATER
                    //            m_currentDate = m_currentDate.AddDays(1);
                    //            m_updated = ReloadScoreboard(null);
                    //            m_mainChannel.UpdateBoxscore(m_currentDate);
                    //            m_lastRefresh = DateTime.Now;
                    //        }
                    //        else if (info.Key == ConsoleKey.M)
                    //        {
                    //            // DO NOTHING
                    //        }
                    //        else if (Modes.GetMode(info.Key) != null)
                    //        {
                    //            Modes.CurrentMode = Modes.GetMode(info.Key);
                    //            UpdateModeData(Modes.CurrentMode.AssociatedKey);
                    //            ShowGameView();
                    //            if (m_mainChannel.ScoreBoard.ActiveTeam != null)
                    //            {
                    //                Modes.CurrentMode = Modes.GetMode(ConsoleKey.M);
                    //                UpdateModeData(Modes.CurrentMode.AssociatedKey);
                    //                ShowGameView();
                    //                m_mainChannel.ScoreBoard.ActiveTeam = null;
                    //            }
                    //        }
                    //    }
                    //}
                    //if (m_updated && m_mainChannel.ScoreBoard.GamesList.Games.Count > 0)
                    //{
                    //    m_updated = false;
                    //    if (m_needBoxes)
                    //    {
                    //        m_boxesManager.InitializeBoxedGames(m_mainChannel.ScoreBoard);
                    //    }
                    //    ShowGameView();
                    //}
                    //Thread.Sleep(100);
                    //TimeSpan currentDelay = DateTime.Now - m_lastRefresh;
                    //int delay = ACTIVE_DELAY_MINUTES;
                    //if (m_mainChannel.ScoreBoard.SelectedGame != null
                    //    && m_mainChannel.ScoreBoard.SelectedGame.Status.Indicator.Category != Indicator.IndicatorCategoy.IN_PROGRESS)
                    //{
                    //    delay = INACTIVE_DELAY_MINUTES;
                    //}
                    //else if (Modes.CurrentMode.AssociatedKey != ConsoleKey.G)
                    //{
                    //    delay = INACTIVE_DELAY_MINUTES;
                    //}
                    //if (currentDelay.TotalMinutes >= delay)
                    //{
                    //    if (m_mainChannel.ScoreBoard.SelectedGame != null)
                    //    {
                    //        m_updated = ReloadScoreboard(m_mainChannel.ScoreBoard.SelectedGame.Id);
                    //        m_mainChannel.UpdateBoxscore(m_currentDate);
                    //        m_lastRefresh = DateTime.Now;
                    //    }
                    //}
                    #endregion
                    if (NEXT_ACTION != "NONE")
                    {
                        if (NEXT_ACTION == "REFRESH")
                        {
                            m_lastRefresh = DateTime.Now;
                            new Thread(new ThreadStart(StartInfoNewsThreads)).Start();
                        }
                        else if (NEXT_ACTION == "STANDINGS")
                        {
                            m_lastRefresh = DateTime.Now;
                            m_mainChannel.UpdateStandings();
                            
                        }
                        else if (NEXT_ACTION == "STATS")
                        {
                            m_lastRefresh = DateTime.Now;
                            m_mainChannel.UpdateStatistics();
                            ModeStatsFormatter formatter = new ModeStatsFormatter();
                            formatter.FormatMode(m_mainChannel.ScoreBoard);
                        }
                        else if (NEXT_ACTION == "QUIT")
                        {
                            m_closing = true;
                            break;
                        }
                        NEXT_ACTION = "NONE";
                    }
                    Thread.Sleep(2000);
                    TimeSpan refreshSpan = DateTime.Now - m_lastRefresh;
                    if (refreshSpan.Minutes > 10)
                    {
                        NEXT_ACTION = "REFRESH";
                    }
                } while (m_closing!=true);
            }
            catch (Exception ex)
            {
                Output.ERROR_MODE = true;
                Output.WriteLine("-- IGG ERROR --");
                Output.WriteLine(ex.Message);
                Output.WriteLine(ex.StackTrace);
                Output.WriteLine();
                Output.WaitForInput();
                m_closing = true;
            }
        }


        /// <summary>
        /// Start threads to feed the news
        /// </summary>
        private void StartInfoNewsThreads()
        {
            m_mainChannel.UpdateNews(false);
            m_mainChannel.UpdateTweets();
            m_mainChannel.UpdateTransactions();
            Output.Clear();
            if (m_mainChannel.ScoreBoard.News != null && m_mainChannel.ScoreBoard.News.Count > 2)
            {
                for (int i = 0; i < 3; i++)
                {
                    Output.WriteLine();
                    Output.WriteLine(" " + m_mainChannel.ScoreBoard.News[i].Title.ToUpper());
                    Output.FormatLongText(m_mainChannel.ScoreBoard.News[i].Content);
                }
            }
            for (int i = 0; i < 4; i++)
            {
                Output.WriteLine();
                Output.WriteLine(" " + m_mainChannel.ScoreBoard.Tweets[i].Author.ToUpper());
                Output.FormatLongText(m_mainChannel.ScoreBoard.Tweets[i].Text);
            }
            new ModeTransactionsFormatter().FormatMode(m_mainChannel.ScoreBoard, 12);
            m_mainChannel.LoadHistory();
            Output.FormatLongText(m_mainChannel.ScoreBoard.History[0]);
            //Output.WriteLine(m_mainChannel.SetBaseballReferenceTidbit());
            Output.WriteLine();
            if (m_mainChannel.ScoreBoard.StandingsNLC!=null && m_mainChannel.ScoreBoard.StandingsNLC.Count > 0)
            {
                ModeDetailedStandingsFormatter formatter = new ModeDetailedStandingsFormatter();
                formatter.FormatMode(m_mainChannel.ScoreBoard);
            }
        }

        /// <summary>
        /// Start threads to feed the news
        /// </summary>
        private void StartGamesThreads()
        {
            m_mainChannel.UpdateNews(false);
            m_mainChannel.UpdateTweets();
            m_mainChannel.UpdateTransactions();
            Output.Clear();

            m_mainChannel.UpdateBoxscore(m_currentDate);
            m_boxesManager.InitializeBoxedGames(m_mainChannel.ScoreBoard);
            m_mainChannel.UpdateAllBoxscores(m_currentDate, m_mainChannel.ScoreBoard);

            if (m_needBoxes && m_mainChannel.ScoreBoard.GamesList.Games.Count > 0)
            {
                m_boxesManager.BuildBoxes(m_mainChannel.ScoreBoard);
                Output.WriteLine();
            }

            Player[] stars = ThreeStarsCalculator.GetThreeStarPlayers(m_mainChannel.ScoreBoard.GamesList.Games);
            if (stars[0] != null && stars[0].GameScore > 0)
            {
                ModeOverviewFormatter.FormatStar(1, stars[0]);
                ModeOverviewFormatter.FormatStar(2, stars[1]);
                ModeOverviewFormatter.FormatStar(3, stars[2]);

                for (int i = 0; i < 3; i++)
                {
                    if (m_mainChannel.ScoreBoard.GamesList.SortedGames.Count > i)
                    {
                        if (ToolBox.YesterdayScores() == false && m_mainChannel.ScoreBoard.GamesList.SortedGames[i].Status.Indicator.IsInProgress)
                        {
                            ModeOverviewFormatter.FormatInProgressGame(m_mainChannel.ScoreBoard.GamesList.SortedGames[i]);
                        }
                        else if (m_mainChannel.ScoreBoard.GamesList.SortedGames[0].Status.Indicator.IsTerminated)
                        {
                            ModeOverviewFormatter.FormatTerminatedGame(m_mainChannel.ScoreBoard.GamesList.SortedGames[i], true);
                        }
                    }
                }
            }
            else
            {
                string start = "Games will start at " + m_mainChannel.ScoreBoard.GamesList.Games[0].StartTime
                    + " " + m_mainChannel.ScoreBoard.GamesList.Games[0].AmPm.ToLower() + ". "
                    + m_mainChannel.ScoreBoard.GamesList.Games.Count + " games today.";
                Output.FormatLongText(start);
                Output.WriteLine();
                ModeOverviewFormatter.FormatNextGame(m_mainChannel.ScoreBoard.GamesList.SortedGames[0]);
            }
            if (m_mainChannel.ScoreBoard.Tweets != null && m_mainChannel.ScoreBoard.Tweets.Length > 0)
            {
                for (int i = 0; i < 5; i++)
                {
                    Output.FormatLongText(m_mainChannel.ScoreBoard.Tweets[i].Author.ToUpper().PadRight(20) + ": " + m_mainChannel.ScoreBoard.Tweets[i].Text);
                }
            }
            if (m_mainChannel.ScoreBoard.News != null && m_mainChannel.ScoreBoard.News.Count > 2)
            {
                for (int i = 0; i < 3; i++)
                {
                    Output.WriteLine();
                    Output.WriteLine(" " + m_mainChannel.ScoreBoard.News[i].Title.ToUpper());
                    Output.FormatLongText(m_mainChannel.ScoreBoard.News[i].Content);
                }
            }

            new ModeTransactionsFormatter().FormatMode(m_mainChannel.ScoreBoard, 6);
            m_mainChannel.LoadHistory();
            Output.FormatLongText(m_mainChannel.ScoreBoard.History[0]);
            //Output.WriteLine(m_mainChannel.SetBaseballReferenceTidbit());
        }


        /// <summary>
        /// Reload the scoreboard as many times as necessary
        /// </summary>
        public bool ReloadScoreboard(string selectedId)
        {
            int maxTries = 8;
            int currentTry = 1;
            int currentDelay = 1000;
            bool success = false;
            while (success == false && currentTry <= maxTries)
            {
                try
                {
                    m_mainChannel.RefreshScoreboard(m_currentDate, selectedId);
                    success = true;
                }
                catch
                {
                    Thread.Sleep(currentDelay);
                    currentDelay = currentDelay * 2;
                }
                finally
                {
                    currentTry++;
                }
            }
            return success;
        }

        /// <summary>
        /// Triggers a data update
        /// </summary>
        /// <param name="key"></param>
        private void UpdateModeData(ConsoleKey key)
        {
            m_needBoxes = true;
            if (key == ConsoleKey.D1 || key == ConsoleKey.D2 || key == ConsoleKey.D3 ||
                key == ConsoleKey.D4 || key == ConsoleKey.D5 || key == ConsoleKey.D6 ||
                key == ConsoleKey.D7 || key == ConsoleKey.D8 || key == ConsoleKey.D9 || key == ConsoleKey.D0)
            {
                if (m_statsLoaded == false)
                {
                    m_mainChannel.UpdateStatistics();
                    m_statsLoaded = true;
                }
            }
            else if (key == ConsoleKey.S || key == ConsoleKey.A)
            {
                m_mainChannel.UpdateStandings();
            }
            else if (key == ConsoleKey.H)
            {
                m_mainChannel.LoadHistory();
            }
            else if (key == ConsoleKey.L || key == ConsoleKey.D)
            {
                m_mainChannel.UpdateTeamAlignment(m_currentDate);
            }
            else if (key == ConsoleKey.B)
            {
                m_mainChannel.UpdateBoxscore(m_currentDate);
            }
            else if (key == ConsoleKey.N)
            {
                m_mainChannel.UpdateNews(false);
            }
            else if (key == ConsoleKey.M)
            {
                m_mainChannel.UpdateTeam();
            }
            else if (key == ConsoleKey.J)
            {
                m_mainChannel.UpdateInjuries();
            }
            else if (key == ConsoleKey.F)
            {
                m_mainChannel.UpdateBaseballReference();
            }
            else if (key == ConsoleKey.R)
            {
                m_mainChannel.UpdateTransactions();
            }
            else if (key == ConsoleKey.Z)
            {
                StartInfoNewsThreads();
            }
            else if (key == ConsoleKey.W)
            {
                m_twitterThreadActive = true;
                m_twitterThread = new Thread(new ThreadStart(RunTwitterThread));
                m_twitterThread.Start();
            }
            else if (key == ConsoleKey.O)
            {
                //m_needBoxes = false;
                m_mainChannel.UpdateTweets();
                m_mainChannel.UpdateAllBoxscores(m_currentDate, m_mainChannel.ScoreBoard);
                m_mainChannel.UpdateNews(false);
            }
        }

        private void RunTwitterThread()
        {
            while (m_twitterThreadActive)
            {
                Output.Clear();
                Output.WriteLine("");
                Output.WriteLine(" Loading Tweets...");
                Output.WriteLine("");
                Output.WriteLine(" Please wait.");
                Output.Clear();
                m_mainChannel.UpdateTweets();
                for (int i = 0; i < 12; i++)
                {
                    Output.WriteLine();
                    Output.WriteLine(" " + m_mainChannel.ScoreBoard.Tweets[i].Author.ToUpper());
                    Output.FormatLongText(m_mainChannel.ScoreBoard.Tweets[i].Text);
                }
                Thread.Sleep(120000);
            }
        }



        /// <summary>
        /// Manage the refreshed event from the main channel
        /// </summary>
        private void m_mainChannel_ScoreboardRefreshed(object sender, EventArgs e)
        {
            m_updated = true;
            m_lastRefresh = DateTime.Now;
        }


        /// <summary>
        /// Show the command line game view
        /// </summary>
        /// <param name="scoreboard"></param>
        private void ShowGameView()
        {
            if (Modes.CurrentMode.AssociatedKey != ConsoleKey.W)
            {
                Output.Clear();
                string title = "MLB Scoreboard for " + ToolBox.GetFormattedDate(m_mainChannel.ScoreBoard.Date)
                    + " (updt @ " + m_mainChannel.ScoreBoard.LastUpdate.ToString("h:mm:ss") + ")";
                Output.SetTitle(title);
                if (m_needBoxes && m_mainChannel.ScoreBoard.GamesList.Games.Count > 0)
                {
                    m_boxesManager.BuildBoxes(m_mainChannel.ScoreBoard);
                    Output.WriteLine();
                }
                Modes.CurrentMode.ModeFormatter.FormatMode(m_mainChannel.ScoreBoard);
            }
        }

        private void MonitorRegistryAction()
        {
            while (m_closing == false)
            {
                try
                {
                    RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\igg", true);
                    RegistryKey myActionKey = null;
                    if (myKey != null)
                    {
                        myActionKey = myKey.OpenSubKey("NextActions", true);
                        object content = myActionKey.GetValue("Action");
                        if (content != null)
                        {
                            if (content.ToString() != "NONE")
                            {
                                NEXT_ACTION = content.ToString();
                                myActionKey.SetValue("Action", "NONE", RegistryValueKind.String);
                            }
                            
                        }
                        myActionKey.Close();
                        myKey.Close();
                    }
                }
                catch (Exception ex)
                {
                    Output.ERROR_MODE = true;
                    Output.WriteLine("Unable to monitor the registry.");
                    Output.WriteLine(ex.Message);
                    Output.WriteLine(ex.StackTrace);
                    Output.WriteLine();
                    Output.WaitForInput();
                }
                Thread.Sleep(5000);
            }
        }
    }
}
